package com.twang.stock.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.twang.stock.Entity.ShiShiData;
import com.twang.stock.common.http.HtmlTools;
import com.twang.stock.design.IndexDataTask;
import com.twang.stock.design.impl.*;
import com.twang.stock.entity.*;
import com.twang.stock.entity.ex.TodayQinXuDto;
import com.twang.stock.mapper.CompanyStockMinutesMapper;
import com.twang.stock.mapper.ThsReDianStockMapper;
import com.twang.stock.mapper.ZhangTingBanMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.service.IndexService;
import com.twang.stock.service.WanZhuBeiChiChangService;
import com.twang.stock.service.ZhangTingBanService;

import com.twang.stock.task.QueryBanKuaiAndDaPan;
import com.twang.stock.task.TodayTrade50AmountTask;
import com.twang.stock.service.ZhangTingBanTaskService;
import com.twang.stock.task.old.BaseTask;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.HolidayCopy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;

@Service
@Slf4j
public class IndexServiceImpl implements IndexService {

    public static  String STOCK_TRADE_SUM="stock_trade_sum";

    public static  String STOCK_TRADE_SUM_1000="stock_trade_sum_1000";


    public static  String STOCK_TRADE_SUM_30_vol="stock_trade_sum_30_vol";
    public static  String STOCK_TRADE_SUM_30_day="stock_trade_sum_30_day";




    @Autowired
    private AsycTaskExecutorConfig asycTaskExecutorConfig;


    @Autowired
    private BaseTask baseTask;

    @Resource
    private TodayTrade50AmountTask todayTrade50AmountTask;

    @Autowired
    @Lazy
    private ZhangTingBanService zhangTingBanService;


    @Resource
    private ThsReDianStockMapper thsReDianStockMapper;
    @Resource
    private CompanyStockMinutesMapper companyStockMinutesMapper;

    @Autowired
    private DfcfBeiShangZiJingTask dfcfBeiShangZiJingTask;

    @Autowired
    private TodayQinXuTask todayQinXuTask;

    @Autowired
    private DfcfBnakKuaisTask dfcfBnakKuaisTask;

    @Autowired
    private DfcfZhangDieModel dfcfZhangDieModel;

    @Autowired
    @Lazy
    private OneThsHotStockListTask oneThsHotStockListTask;

    @Autowired
    @Lazy
    private ThsHotStockListTask thsHotStockListTask;

    @Autowired
    @Lazy
    private  ZhangDieTingTask zhangDieTingTask;

    @Autowired
    private ZhangTingBanTaskService zhangTingBanTaskService;

    @Autowired
    private ZiXuanBanKuaiTask ziXuanBanKuaiTask;

    @Autowired
    private SumTotalTradeAmountTask sumTotalTradeAmountTask;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ZhangTingJuJiaoTask zhangTingJuJiaoTask;


    @Resource
    private ZhangTingBanMapper zhangTingBanMapper;

    @Autowired
    private WanZhuBeiChiChangService wanZhuBeiChiChangService;



    @Override
    public void indexDataInitNew(ModelAndView modelAndView) throws Exception {

        final  CountDownLatch latch = new CountDownLatch(10);
        //北上资金
        executeIndexDataTask(modelAndView, latch, dfcfBeiShangZiJingTask);
        //获取今日板块涨幅排行
        executeIndexDataTask(modelAndView, latch, todayQinXuTask);
        //今日板块涨幅排行
        executeIndexDataTask(modelAndView, latch, dfcfBnakKuaisTask);
        //大盘数据
        executeIndexDataTask(modelAndView, latch, dfcfZhangDieModel);
        //1小时同花顺热度榜单
        executeIndexDataTask(modelAndView, latch, oneThsHotStockListTask);
        //24小时同花顺热度榜单
        executeIndexDataTask(modelAndView, latch, thsHotStockListTask);
        //大盘涨跌情况
        executeIndexDataTask(modelAndView, latch, zhangDieTingTask);
        //板块
        executeIndexDataTask(modelAndView, latch, ziXuanBanKuaiTask);
        //成交量
        executeIndexDataTask(modelAndView, latch, sumTotalTradeAmountTask);
        //涨幅前20榜单
       // executeIndexDataTask(modelAndView, latch, wenCaiDataTask);
        //涨停聚焦
        executeIndexDataTask(modelAndView, latch, zhangTingJuJiaoTask);

        //

        //判断是否需要刷新
        isReflash(modelAndView);
        latch.await(); //等待,不断检测数量是否为0，为零是执行后面的操作

    }

    /**
     * 判断是否需要刷新
     * @param modelAndView
     */
    @Override
    public void isReflash(ModelAndView modelAndView) {
        /** 判断是否需要刷新*/
        if (baseTask.isWorkTradeTime()) {
            modelAndView.addObject("isFlash", 1);
        } else {
            modelAndView.addObject("isFlash", 0);
        }
        /** 更新情绪*/
        Object object= modelAndView.getModelMap().get("zhangTingBanList_DTC");
        if(null!=object){
            List<ZhangTingJuJiao> list = (List<ZhangTingJuJiao>) object;
            if(list.size()>10){
                modelAndView.addObject("LNQX",SumTotalTradeAmountTask.LNQX_5);
            }
        }
        modelAndView.addObject("consumerQueen", 0);
    }

    private void executeIndexDataTask(ModelAndView modelAndView, CountDownLatch latch, IndexDataTask task) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                task.execute(modelAndView,latch);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                log.info("当前执行条数:{}", latch.getCount());
                //latch.countDown();
            }
        });
    }

    @Override
    public void indexDataInit(ModelAndView modelAndView) throws Exception {
        final CountDownLatch latch = new CountDownLatch(6);
        初始化各个模块数据(modelAndView, latch);
        latch.await();//等待,不断检测数量是否为0，为零是执行后面的操作
        wanZhuBeiChiChangService.根据日期更新玩主杯热榜(HolidayCopy.getToday());

    }

    private void 初始化各个模块数据(ModelAndView modelAndView, CountDownLatch latch) {
        /** 1-沪深指数*/
        沪深指数(modelAndView, latch);

        /** 2-北上资金 */
        北上资金(modelAndView, latch);


        /** 3-概念板块 */
        概念板块(modelAndView, latch);


        /** 判断是否需要刷新*/
        if(baseTask.isWorkTradeTime()){
            modelAndView.addObject("isFlash",1);
        }else {
            modelAndView.addObject("isFlash",0);
        }

        /** 4-24小时同花顺热度榜单 */
        同花顺热度榜单24(modelAndView, latch, thsReDianStockMapper.select24HourData(), "thsHotStockList", "24小时同花顺热度榜单 = {}");


        /** * 5-1小时同花顺热度榜单 */
        同花顺热度榜单24(modelAndView, latch, thsReDianStockMapper.selectOneHourData(), "onethsHotStockList", "1小时同花顺热度榜单 ={} ");


        /** * 6-今日大盘 */
        今日大盘(modelAndView, latch);
    }

    private void 今日大盘(ModelAndView modelAndView, CountDownLatch latch) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                TodayQinXuDto todayQinXu = QueryBanKuaiAndDaPan.getTodayQinXu();
                modelAndView.addObject("todayQinXu",todayQinXu);
                log.info("今日大盘 = ", JSONObject.toJSONString(todayQinXu));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                log.info("当前执行条数:{}", latch.getCount());
                latch.countDown();
            }
        });
    }

    private void 同花顺热度榜单24(ModelAndView modelAndView, CountDownLatch latch, List<ThsReDianStock> thsReDianStocks, String thsHotStockList2, String s) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                List<ThsReDianStock> list = thsReDianStocks;
                List<ThsHotStock> thsHotStockList = Lists.newArrayList();
                getThsHotStockList(list, thsHotStockList, 5);
                modelAndView.addObject(thsHotStockList2, thsHotStockList);
                log.info(s, JSONObject.toJSONString(thsHotStockList));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                log.info("当前执行条数:{}", latch.getCount());
                latch.countDown();
            }
        });
    }

    private void 概念板块(ModelAndView modelAndView, CountDownLatch latch) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                List<DfcfBnakKuai> dfcfBnakKuais = QueryBanKuaiAndDaPan.geBKZF("");
                modelAndView.addObject("dfcfBnakKuais",dfcfBnakKuais);
                log.info("概念板块 ={} ", JSONObject.toJSONString(dfcfBnakKuais));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                log.info("当前执行条数:{}", latch.getCount());
                latch.countDown();
            }
        });
    }

    private void 北上资金(ModelAndView modelAndView, CountDownLatch latch) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                HkShMoneyInOut hkShMoneyInOut = QueryBanKuaiAndDaPan.getHGTInOut();
                modelAndView.addObject("bszj",hkShMoneyInOut);
                log.info("沪港通,北上={} ", JSONObject.toJSONString(hkShMoneyInOut));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                log.info("当前执行条数:{}", latch.getCount());
                latch.countDown();
            }
        });
    }

    private void 沪深指数(ModelAndView modelAndView, CountDownLatch latch) {
        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                List<DfcfZhangDie> dfcfZhangDies = QueryBanKuaiAndDaPan.getDfcfZhangDie();
                dfcfZhangDies.forEach(item -> {
                    if ("000001".equals(item.getTypeCode())) {
                        modelAndView.addObject("sh", item);
                    } else {
                        modelAndView.addObject("sz", item);
                    }
                });
                log.info("沪深 = {}", JSONObject.toJSONString(dfcfZhangDies));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                log.info("当前执行条数:{}", latch.getCount());
                latch.countDown();
            }
        });
    }


    /**
     *
     * @param list
     */
    @Override
    public void getThsHotStockList(List<ThsReDianStock> list, List<ThsHotStock> thsHotStockList,int size)  {
        for(int i=0;i<=size;i++){
            ThsReDianStock thsReDianStock= list.get(i);
            ThsHotStock item=new ThsHotStock();
            BeanUtils.copyProperties(thsReDianStock,item);
            item.setZhangdie(thsReDianStock.getZhangDie());
            item.setOrder(thsReDianStock.getStockOrder().intValue());
            if(StringUtils.isNotBlank(thsReDianStock.getSustainTags())){
                item.setSustainTags(JSONObject.parseArray(thsReDianStock.getSustainTags(),ThsGeGuReZDianSustainTags.class));
            }
            //设置涨停原因
            getReason(thsReDianStock, item);
            thsHotStockList.add(item);
        }
    }

    /**
     *涨停原因
     * @param thsReDianStock
     * @param item
     */
    public String getReason(ThsReDianStock thsReDianStock, ThsHotStock item) {

        try{
            ZhangTingBan zhangTingBanTemp=new ZhangTingBan();
            zhangTingBanTemp.setCode(thsReDianStock.getCode());
            KaiPanLa kaiPanLa=zhangTingBanTaskService.kaipanLaZhangTingReason(HolidayCopy.getToday(),zhangTingBanTemp);
            if(null!=kaiPanLa) {
                List<KaiPanLaBaseInfo> kaiPanLaBaseInfos = kaiPanLa.getList();
                if(!CollectionUtils.isEmpty(kaiPanLaBaseInfos)){
                    String bankuai = kaiPanLaBaseInfos.get(0).getReason();
                    bankuai = bankuai.split("；")[0];
                    log.info(">>>>>>>>>> getThsHotStockList code={} name={} reason={}",zhangTingBanTemp.getCode(), item.getName(),bankuai);
                    item.setMarket(bankuai);
                    return bankuai;
                }
            }
        }catch (Exception e){
            log.error(">>>>>>>>> getThsHotStockList error:",e);
        }
        return "-";
    }

    @Override
    public  List<DfcfBanKuaiMaoLiLv>  chengJiaoE() {
        List<DfcfBanKuaiMaoLiLv> maoLiLvs = Lists.newArrayList();
        try {
            List<CompanyStockMinutes> list = todayTrade50AmountTask.getTradeAmountDESC(null, companyStockMinutesMapper.queryYesterDayNew());
            return getDfcfBanKuaiMaoLiLvs(maoLiLvs, list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<DfcfBanKuaiMaoLiLv> getDfcfBanKuaiMaoLiLvs(List<DfcfBanKuaiMaoLiLv> maoLiLvs, List<CompanyStockMinutes> list) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        int number = list.size() > 99 ? 100 : list.size();
        for (int i = 0; i < number; i++) {
            CompanyStockMinutes companyStockMinutes = list.get(i);
            /** * 6-今日大盘 */
            try {
                if(null==companyStockMinutes){
                    continue;
                }
                String code = companyStockMinutes.getCompanyCode().replace("sz", "").replace("sh", "");
                String stockCode = companyStockMinutes.getCompanyCode();
                DfcfBanKuaiMaoLiLv dfcfBanKuaiMaoLiLv = new DfcfBanKuaiMaoLiLv();
                dfcfBanKuaiMaoLiLv.setCode(code);
                dfcfBanKuaiMaoLiLv.setName(companyStockMinutes.getCompanyName());
                dfcfBanKuaiMaoLiLv.setMll(companyStockMinutes.getZhangDie());
                dfcfBanKuaiMaoLiLv.setZrZhangDie(companyStockMinutesMapper.queryYesterZhangDie(companyStockMinutes.getCompanyCode(), companyStockMinutes.getDate()));
                dfcfBanKuaiMaoLiLv.setLianXuZhang(this.isLianXuShangZhang(dfcfBanKuaiMaoLiLv));
                dfcfBanKuaiMaoLiLv.setCje(companyStockMinutes.getTradeSum());
                List<ThsGeGuReZDian> thsGeGuReZDianList = QueryBanKuaiAndDaPan.查询个股热点(code);
                //查询涨停原因
                ThsGeGuReZDian thsGeGuReZDian = new ThsGeGuReZDian();
                thsGeGuReZDian.setTagName("历史涨停原因");
                String ztDesc = zhangTingBanService.zhangtingReason(stockCode);
                if (StringUtils.isNotBlank(ztDesc)) {
                    thsGeGuReZDian.setZtDesc(ztDesc);
                }
                //
                thsGeGuReZDianList.add(thsGeGuReZDian);
                dfcfBanKuaiMaoLiLv.setKanDian(thsGeGuReZDianList);
                maoLiLvs.add(dfcfBanKuaiMaoLiLv);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        log.info("成交额 数据：{}= ", JSONObject.toJSONString(maoLiLvs));
        return maoLiLvs;
    }

    @Override
    public List 获取市场高度( ModelAndView modelAndView) {
        String shichanggaodu_day = "shichanggaodu_day_" + HolidayCopy.getRealToday();
        String shichanggaodu_gaodu = "shichanggaodu_gaodu_" + HolidayCopy.getRealToday();
        Object object = redisUtil.get(shichanggaodu_day);
        Object objectGaodu = redisUtil.get(shichanggaodu_gaodu);
        if (null != object) {
            List<String> days = JSONObject.parseArray(object.toString(), String.class);
            List<Integer> gaoDu = JSONObject.parseArray(objectGaodu.toString(), Integer.class);
            modelAndView.addObject("days", days);
            modelAndView.addObject("gaoDu", gaoDu);
            modelAndView.addObject("toDayGaoDu", gaoDu.get(gaoDu.size()-1));
        } else {
            List<String> days = zhangTingBanMapper.queryAllDays();
            List<Integer> gaoDu = Lists.newArrayList();
            days.stream().forEach(item -> {
                Integer lbc = zhangTingBanMapper.queryLbc(item);
                gaoDu.add(lbc);
            });
            redisUtil.set(shichanggaodu_day, JSONObject.toJSONString(days));
            redisUtil.set(shichanggaodu_gaodu,  JSONObject.toJSONString(gaoDu));
            modelAndView.addObject("days", days);
            modelAndView.addObject("gaoDu", gaoDu);
            modelAndView.addObject("toDayGaoDu", gaoDu.get(gaoDu.size()-1));
        }

        return null;
    }

    @Override
    public List 获取市场涨停成交额(ModelAndView modelAndView) {
        String shichanglbcje_day = "shichanglbcje_day_" + HolidayCopy.getRealToday();
        String shichanglbcje_cje = "shichanglbcje_cje_" + HolidayCopy.getRealToday();
        Object object = redisUtil.get(shichanglbcje_day);
        Object objectAmount = redisUtil.get(shichanglbcje_cje);
        if (null != object) {
            List<String> days = (List<String>) object;
            List<BigDecimal> amount = (List<BigDecimal>) objectAmount;
            modelAndView.addObject("days", days);
            modelAndView.addObject("cje", amount);
            modelAndView.addObject("toDayCje", amount.get(amount.size()-1).setScale(2,BigDecimal.ROUND_HALF_UP));
        } else {
            List<String> days = zhangTingBanMapper.queryAllDays();
            List<BigDecimal> amount = Lists.newArrayList();
            days.stream().forEach(item -> {
                BigDecimal lbc = zhangTingBanMapper.queryLbcAmount(item);
                if(null!=lbc){
                    amount.add(lbc.setScale(2,BigDecimal.ROUND_HALF_UP));
                }else{
                    amount.add(BigDecimal.ZERO);
                }
            });
            redisUtil.set(shichanglbcje_day, days, 60 * 60 * 24);
            redisUtil.set(shichanglbcje_cje, amount,60 * 60 * 24);
            modelAndView.addObject("days", days);
            modelAndView.addObject("cje", amount);
            modelAndView.addObject("toDayCje", amount.get(amount.size()-1).setScale(2,BigDecimal.ROUND_HALF_UP));
        }
        return null;
    }


    public Boolean isLianXuShangZhang(DfcfBanKuaiMaoLiLv dfcfBanKuaiMaoLiLv ) {
        try {
            if (dfcfBanKuaiMaoLiLv.getMll().compareTo(BigDecimal.ZERO) >= 1 && (dfcfBanKuaiMaoLiLv.getZrZhangDie().compareTo(BigDecimal.ZERO) >= 1)) {
                return Boolean.TRUE;
            }
        } catch (Exception e) {

        }
        return Boolean.FALSE;
    }

    @Override
    public String getOneStockInfo(String code) throws Exception {
        String key="STOCKKANDIAN_"+code+"_"+HolidayCopy.getRealToday();
        Object obj = redisUtil.get(key);
        if (null == obj) {
            List<DfcfBanKuaiMaoLiLv> maoLiLvs = Lists.newArrayList();
            String stockCode = "";
            if (code.startsWith("3") || code.startsWith("0")) {
                stockCode = "sz" + code;
            } else {
                stockCode = "sh" + code;
            }
            List<ShiShiData> shiShiDataList = HtmlTools.getGpdatas(Lists.newArrayList(stockCode));
            DfcfBanKuaiMaoLiLv dfcfBanKuaiMaoLiLv = new DfcfBanKuaiMaoLiLv();
            dfcfBanKuaiMaoLiLv.setCode(code);
            dfcfBanKuaiMaoLiLv.setName(shiShiDataList.get(0).getGpname());
            dfcfBanKuaiMaoLiLv.setMll(shiShiDataList.get(0).getZhangdie());
            List<ThsGeGuReZDian> thsGeGuReZDianList = QueryBanKuaiAndDaPan.查询个股热点(code);
            //查询涨停原因
            String ztDesc = zhangTingBanService.zhangtingReason(stockCode);
            if (StringUtils.isNotBlank(ztDesc)) {
                ThsGeGuReZDian thsGeGuReZDian = new ThsGeGuReZDian();
                thsGeGuReZDian.setTagName("历史涨停原因");
                thsGeGuReZDian.setZtDesc(ztDesc);
                //
                thsGeGuReZDianList.add(thsGeGuReZDian);
            }
            dfcfBanKuaiMaoLiLv.setKanDian(thsGeGuReZDianList);
            maoLiLvs.add(dfcfBanKuaiMaoLiLv);
            zhangTingBanTaskService.initKanDian(maoLiLvs, Boolean.FALSE);
            //Cache
            if (!CollectionUtils.isEmpty(maoLiLvs)) {
                String str = JSONObject.toJSONString(maoLiLvs);
                redisUtil.set(key, str);
                obj=str;
            }
        }
        return obj.toString();
    }
}
